package com.batch;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.io.BufferedReader;
import java.io.FileReader;


import com.bean.GabBean;
import com.hibernate.*;
public class ControlesVAD {

	private int champ39=0;
	private String numCarte;
	private String code;
	private boolean valide=false;
	private static int nbrEssai = 0;
	private static Operation op = new Operation();
	Date date = new Date();
	Timestamp tmp = new Timestamp(date.getTime());
	private boolean garderCarte= false;


	public Operation getOp() {
		return op;
	}
	public void setOp(Operation op) {
		this.op = op;
	}
	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	public int getChamp39() {
		return champ39;
	}
	public void setChamp39(int champ39) {
		this.champ39 = champ39;
	}


	// aqcuisition operation et debut de controle
	public int acuisitionOperation(String numCarte)
	{

		this.numCarte=numCarte;
	
		return validiteCarte(numCarte);
	}

	// validite carte si elle ne commence pas par 4(visa) ou 5(mastercard)
	public int validiteCarte(String numCarte)
	{

		String numCarte2 = numCarte.substring(0,1);

		if(numCarte2.equals("5") || numCarte2.equals("4"))
		{
			return verificationCarte( numCarte);
		}
		else 
		{
			return champ39=3;

		}

	}

	


	// verification depuis fichier
	public String verifierIdentite()
	{ 
		CarteDAO dao = new CarteDAO();
		dao.getSession().getTransaction().begin();
		try
		{
		Carte carte = dao.findById(Integer.parseInt(numCarte));
		if (carte.getNumerocarte() == Integer.parseInt(numCarte))
		{
			valide = true;
		}
		}
		catch(Exception e)
		{
			valide= false;
		}
		return "ok";
		
	}



	//verificatuion existance carte
	public int verificationCarte(String numCarte)
	{
		verifierIdentite();

		if(valide == true)
		{   // enregistrement de l operation

			AccepteurDAO daoA = new AccepteurDAO();
			daoA.getSession().getTransaction().begin();
			Accepteur accepteur = daoA.findById(11);
			CarteDAO daoC = new CarteDAO();
			daoC.getSession().getTransaction().begin();
			Carte carte = daoC.findById(Integer.parseInt(numCarte));
			OperationDAO dao = new OperationDAO();
			dao.getSession().getTransaction().begin();
			try {

				op = new Operation(carte,accepteur,0.0,tmp,champ39,nbrEssai,champ39,champ39,carte.getDateexpirationcarte(),champ39,tmp,tmp,champ39,champ39,champ39,champ39,champ39,champ39);
				dao.save(op);
				dao.getSession().getTransaction().commit();
			}
			catch(Exception e)
			{

			}
			return validiteDateCarte(carte);
		}
		return champ39 =8;
	}


	// verification par rapport a la date d expiration de la carte
	public int validiteDateCarte(Carte carte)
	{

		if(tmp.before(carte.getDateexpirationcarte()))
		{

			return statutCarte(carte);
		}
		else  
		{

			champ39 = 7;
			OperationDAO dao = new OperationDAO();
			dao.getSession().getTransaction().begin();
			op.setChamp39operation(7);
			dao.getSession().getTransaction().commit();
			delivrance_autorisation(carte,"KO");
			return champ39;

		}


	}

	// veirification si la carte et active ou pas 0--< action 1--> non active
	public int statutCarte(Carte carte)
	{

		if(carte.getStatutcarte()==0)
		{

			return oppositionCarte(carte);
		}
		else 
		{   champ39 =12;
		OperationDAO dao = new OperationDAO();
		dao.getSession().getTransaction().begin();
		op.setChamp39operation(12);
		dao.getSession().getTransaction().commit();
		delivrance_autorisation(carte,"KO");
		return champ39;
		}

	}
	// verification si la carte est en opposition 0(perte) 1(vole) 2(fraude)
	public int  oppositionCarte(Carte carte)
	{

		OppositionDAO opDAO = new OppositionDAO(); 
		opDAO.getSession().getTransaction().begin();
		try{
			Opposition op = opDAO.findById(carte.getNumerocarte());
			if(op.getMotifopposition()==0 )
				champ39 = 49;
			if(op.getMotifopposition()==1 )
				champ39 = 32;
			if(op.getMotifopposition()==2 )
				champ39 = 26;
		}
		catch(Exception er)
		{


		}
		if(champ39!=0)
		{


			OperationDAO dao = new OperationDAO();
			dao.getSession().getTransaction().begin();
			op.setChamp39operation(champ39);
			dao.getSession().getTransaction().commit();
			delivrance_autorisation(carte,"KO");
			return champ39;

		}
		else return  cvv2Carte(carte);
	}

	public int cvv2Carte(Carte carte)
	{

		return cleLuhn(carte);

	}

	// algorithme cle luhne
	public int cleLuhn(Carte carte)
	{ 

		int size = String.valueOf(carte.getNumerocarte()).length();
		int somme = 0;

		for(int i = 0;i<size; i++)
		{
			if( 
					i%2 == 0 )	
			{

				if((Integer.parseInt((carte.getNumerocarte().toString().substring(i,i+1)))*2) >= 10)
				{

					int val_1 = (Integer.parseInt((carte.getNumerocarte().toString().substring(i,i+1)))*2);
					String val_2 = String.valueOf(val_1);
					int val = Integer.parseInt(val_2.substring(0, 1))+ Integer.parseInt(val_2.substring(1, 2));

					somme = somme +val;
				}

				else somme = somme+ (Integer.parseInt((carte.getNumerocarte().toString().substring(i,i+1)))*2);

			}
			else somme = somme+ Integer.parseInt((carte.getNumerocarte().toString().substring(i,i+1)));

		}
		if(somme%10 != 0)

		{   champ39 =10;
		OperationDAO dao = new OperationDAO();
		dao.getSession().getTransaction().begin();
		op.setChamp39operation(champ39);
		dao.getSession().getTransaction().commit();

		delivrance_autorisation(carte,"KO");
		return champ39;
		}
		else  nbrEssai=0; // reinitialiser nbr de conx;

		return champ39;
	}


	// debut controle financier
	public int controleFinanciers(Carte carte,double montant,short var)
	{

		OperationDAO dao = new OperationDAO();
		dao.getSession().getTransaction().begin();
		ArrayList<Operation> operat =  (ArrayList<Operation>) dao.findByExample(op);
		operat.get(0).setTypeoperation("retrait");
		operat.get(0).setMontantoperation(montant);
		dao.getSession().getTransaction().commit();
		if(montant%50 == 0 )
		{

			return  plafondEncour(carte,montant,var);
		}


		else 
		{
			delivrance_autorisation(carte,"KO");
			return 1;
		}
	}


	// controle encours par rapport au plafin var= 0 retrait var= 1 paiement
	public int plafondEncour(Carte carte,double montant,short var)
	{

		EncoursDAO dao = new EncoursDAO();
		EncoursId encoursId = new EncoursId(carte,var);
		Encours encours = dao.findById(encoursId);


		// controle avec date debut encours 
		if(encours.getDatedebutencours()==null)
		{
			GregorianCalendar calendar = new java.util.GregorianCalendar(); 
			encours.setDatedebutencours(tmp);
			int jour = encours.getDureeglissementencours();
			calendar.add(calendar.DATE,jour);
			Timestamp datefin = new Timestamp(calendar.getTime().getTime()) ;
			encours.setDatereinitialisationencours(datefin);

		}
		// reinitialisation de la date 
		if(tmp.after(encours.getDatereinitialisationencours()))
		{
			GregorianCalendar calendar = new java.util.GregorianCalendar(); 
			encours.setDatedebutencours(tmp);
			int jour = encours.getDureeglissementencours();
			calendar.add(calendar.DATE,jour);
			Timestamp datefin = new Timestamp(calendar.getTime().getTime()) ;
			encours.setDatereinitialisationencours(datefin);
			encours.setMontantencours(0.0);
		}

		// verification encours avec plafond

		if(encours.getMontantencours()==null)
		{
			encours.setMontantencours(0.0);
		}
		if((encours.getMontantencours()+montant) <= encours.getPlafondencours())
			return solde(carte,montant,var);
		else 
		{  
			delivrance_autorisation(carte,"KO");
			return 1;
		}
	}

	// solde insuffisant ou pas
	public int solde(Carte carte, double montant,short var)
	{

		if((carte.getComptebancaire().getSoldecomptebancaire()-10) > montant)
		{

			EncoursDAO dao = new EncoursDAO();
			dao.getSession().getTransaction().begin();
			EncoursId encoursId = new EncoursId(carte,var);
			Encours encours = dao.findById(encoursId);
			encours.setMontantencours(encours.getMontantencours()+montant);
			carte.getComptebancaire().setSoldecomptebancaire(carte.getComptebancaire().getSoldecomptebancaire()-montant);
			delivrance_autorisation(carte,"OK");
			return 0;

		}

		else return 1;
	}

	// delivrance de l'autorisation
	public void delivrance_autorisation(Carte carte,String statut)
	{
		AutorisationDAO dao = new AutorisationDAO();
		dao.getSession().getTransaction().begin();
		GabBean gab = new GabBean();
		Autorisation aut = new Autorisation(statut,tmp,op,gab.isTicketChoix());
		gab.setTicketChoix(false);
		dao.save(aut);
		dao.getSession().getTransaction().commit();
	}

	public boolean suffisant(Carte carte,double montant,short var)
	{
		
		EncoursDAO dao = new EncoursDAO();
		EncoursId encoursId = new EncoursId(carte,var);
		Encours encours = dao.findById(encoursId);

		OperationDAO daop = new OperationDAO();
		daop.getSession().getTransaction().begin();
		ArrayList<Operation> operat =  (ArrayList<Operation>) daop.findByExample(op);
		System.out.println("dae "+encours.getDatedebutencours());
		// controle avec date debut encours 
		if(encours.getDatedebutencours()==null)
		{
			System.out.println("solde" + carte.getComptebancaire().getSoldecomptebancaire());
			
			if((carte.getComptebancaire().getSoldecomptebancaire()-10) > montant && montant%50==0)
				return true;
			else 

			{	System.out.println("daed ");
				operat.get(0).setTypeoperation("retrait");
				operat.get(0).setMontantoperation(montant);
				daop.getSession().getTransaction().commit();
				delivrance_autorisation(carte,"KO");
				return 	false;
			}


		}
		System.out.println("daed2 ");
		// reinitialisation de la date 
		if(tmp.after(encours.getDatereinitialisationencours()))
		{
			if((carte.getComptebancaire().getSoldecomptebancaire()-10) > montant && montant%50==0)
				return true;
			else 
			{
				operat.get(0).setTypeoperation("retrait");
				operat.get(0).setMontantoperation(montant);
				daop.getSession().getTransaction().commit();
				delivrance_autorisation(carte,"KO");
				return 	false;
			}
		}

		// verification encours avec plafond 
		if(tmp.before(encours.getDatereinitialisationencours()))
		{
			if(encours.getMontantencours()==null)
			{
				encours.setMontantencours(0.0);
			}

			if((encours.getMontantencours()+montant) <= encours.getPlafondencours())
			{
				if((carte.getComptebancaire().getSoldecomptebancaire()-10) > montant && montant%50==0)
					return true;
				else 

				{	
					operat.get(0).setTypeoperation("retrait");
					operat.get(0).setMontantoperation(montant);
					daop.getSession().getTransaction().commit();
					delivrance_autorisation(carte,"KO");
					return 	false;
				}

			}
			else 
			{	
				operat.get(0).setTypeoperation("retrait");
				operat.get(0).setMontantoperation(montant);
				daop.getSession().getTransaction().commit();
				delivrance_autorisation(carte,"KO");
				return 	false;
			}
		}
		else 
		{	
			operat.get(0).setTypeoperation("retrait");
			operat.get(0).setMontantoperation(montant);
			daop.getSession().getTransaction().commit();
			delivrance_autorisation(carte,"KO");
			return 	false;
		}


	}

}
